/**
 * 
 */
package com.sdu.passager.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.sdu.passager.bean.TableBean;
import com.sdu.passager.common.DateUtility;
import com.sdu.passager.common.Dic;

import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * @author Administrator
 * 
 */
public class CodeGen {

	private Logger log = Logger.getLogger(this.getClass());
	private FreeMarkerConfigurer freeMarkerConfigurer;
	private TableUtil tableUtil;// ///数据库组装类
	private static List<TableBean> tableBeans = null;
	private String outputDirectoryroot;// //代码生成的根目录
	private String outputDirectorymodel;// /model存放路径
	private String outputDirectoryservice;// /service存放路径
	private String outputDirectorydao;// /dao存放路径
	private String outputDirectorydaoImpl;// /daoImpl存放路径
	private String outputDirectoryserviceImpl;// /serviceImpl存放路径
	private String outputDirectoryaction;// //action存放路径
	private String author;
	private String projectName;
	private String schema;//////表的schema


	//
	/**
	 * 获得转换的列表
	 * 
	 * @return
	 */
	public List<TableBean> getTableBeans() {
		if (tableBeans == null)
			return tableUtil.getTableBeans();
		return tableBeans;
	}

	@SuppressWarnings("unchecked")
	public String getContentFromTemplate(Map map, String ftlname) {
		String htmlText = "";
		Template tpl = null;
		try {
			tpl = freeMarkerConfigurer.getConfiguration().getTemplate(ftlname);// 加载资源文件
			htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(tpl,
					map);// 加入map到模板中 对应${content}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		return htmlText;
	}

	//
	/**
	 * 根据model模板生成代码
	 * 
	 * @param map
	 * @param ftlname
	 */
	@SuppressWarnings("unchecked")
	public void  fltCodeGen() {
		
		// //获得处理的列表
		List<TableBean> list = this.getTableBeans();

		// //遍历tableBean对flt处理值
		for (TableBean tb : list) {
			

			Template template = null;
			FileOutputStream fos = null;
			Writer writer = null;
			File file = null;
			
			String nameStr = tb.getTableClassName();
			nameStr = doChange(nameStr);
			try {
				log.info("-------------model Gen start-------------");
				String filePath = this.getOutputDirectoryroot()+File.separator
										+ this.getOutputDirectorymodel()+File.separator
										+ tb.getTableClassName() + Dic.JAVASUF;
				file = new File(filePath);
				if(file.exists())
					file.delete();
				
				Map modelmap = new HashMap();
				modelmap.put("projectName", this.getProjectName());
				modelmap.put("author", this.getAuthor());
				modelmap.put("datetime", DateUtility.getFormatDate(DateUtility .getCurrentTime(), DateUtility.DateTimeFormat));
				modelmap.put("package", outputDirectorymodel.replaceAll("/", "."));
				modelmap.put("tableName", tb.getTableName());
				modelmap.put("modelName", tb.getTableClassName());
				modelmap.put("listfields", tb.getFields());
				modelmap.put("schema", this.getSchema());//2012年7月31日11:14:58 add
				modelmap.put("sqlName", tb.getSeqName());///2013年1月14日15:34:48 add
				modelmap.put("modelMic", nameStr);	//首字母小写
				
				// /文件生成的文件路径不存在进行直接生成
				file = new File(this.getOutputDirectoryroot()+File.separator+ this.getOutputDirectorymodel());
				if (!file.exists())
					file.mkdirs();
				fos = new FileOutputStream(filePath);
				writer = new OutputStreamWriter(fos, Dic.UTF_8);
				template = freeMarkerConfigurer.getConfiguration().getTemplate(Dic.MODEL_FLT);
				template.process(modelmap, writer, new DefaultObjectWrapper());
				log.info("-------------model Gen end-------------");
				
				log.info("-------------Service Gen start-------------");
				filePath = this.getOutputDirectoryroot()+File.separator
						+ this.getOutputDirectoryservice()+File.separator
						+ tb.getTableClassName()+Dic.SERVICE + Dic.JAVASUF;
				file = new File(filePath);
				if(file.exists()) 
					file.delete();
				Map managerMap = new HashMap();
				managerMap.put("projectName", this.getProjectName());
				managerMap.put("author", this.getAuthor());
				managerMap.put("datetime", DateUtility.getFormatDate(DateUtility.getCurrentTime(), DateUtility.DateTimeFormat));
				
				managerMap.put("package", outputDirectoryservice.replaceAll("/", "."));
				managerMap.put("modelimport", outputDirectorymodel.replaceAll("/", ".")+"."+tb.getTableClassName());
				managerMap.put("modelName", tb.getTableClassName());
				managerMap.put("modelMic", nameStr);	//首字母小写
				// /文件生成的文件路径不存在进行直接生成
				file = new File(this.getOutputDirectoryroot()+File.separator
						+ this.getOutputDirectoryservice());
				if (!file.exists())
					file.mkdirs();

				fos = new FileOutputStream(filePath);
				writer = new OutputStreamWriter(fos, Dic.UTF_8);
				template = freeMarkerConfigurer.getConfiguration().getTemplate(Dic.SERVICE_FLT);
				template.process(managerMap, writer, new DefaultObjectWrapper());
				log.info("-------------service Gen end-------------");

				log.info("-------------ServiceImpl Gen start-------------");
				filePath = this.getOutputDirectoryroot()+File.separator + this.getOutputDirectoryserviceImpl()+File.separator
					+ tb.getTableClassName()+Dic.SERVICE_IMPL + Dic.JAVASUF;
				file = new File(filePath);
				if(file.exists()) 
					file.delete();
				Map managerImplMap = new HashMap();
				managerImplMap.put("projectName", this.getProjectName());
				managerImplMap.put("author", this.getAuthor());
				managerImplMap.put("datetime", DateUtility.getFormatDate(DateUtility.getCurrentTime(), DateUtility.DateTimeFormat));
				
				managerImplMap.put("package", outputDirectoryserviceImpl.replaceAll("/", "."));
				managerImplMap.put("modelimport", outputDirectorymodel.replaceAll("/", ".")+"."+tb.getTableClassName());
				managerImplMap.put("modelName", tb.getTableClassName());
				managerImplMap.put("modelMic", nameStr);	//首字母小写
				// /文件生成的文件路径不存在进行直接生成
				file = new File(this.getOutputDirectoryroot()+File.separator + this.getOutputDirectoryserviceImpl());
				if (!file.exists())
					file.mkdirs();
				
				fos = new FileOutputStream(filePath);
				writer = new OutputStreamWriter(fos, Dic.UTF_8);
				template = freeMarkerConfigurer.getConfiguration().getTemplate(Dic.SERVICE_IMPL_FLT);
				template.process(managerMap, writer, new DefaultObjectWrapper());
				log.info("-------------ServiceImpl Gen end-------------");
				
				
				
				
				
				
				
				
				
				
				log.info("-------------dao Gen start-------------");
				filePath = this.getOutputDirectoryroot()+File.separator
						+ this.getOutputDirectorydao()+File.separator
						+ tb.getTableClassName()+Dic.DAO + Dic.JAVASUF;
				file = new File(filePath);
				if(file.exists()) 
					file.delete();
				Map daoMap = new HashMap();
				daoMap.put("projectName", this.getProjectName());
				daoMap.put("author", this.getAuthor());
				daoMap.put("datetime", DateUtility.getFormatDate(DateUtility.getCurrentTime(), DateUtility.DateTimeFormat));
				
				daoMap.put("package", outputDirectorydao.replaceAll("/", "."));
				daoMap.put("modelimport", outputDirectorymodel.replaceAll("/", ".")+"."+tb.getTableClassName());
				daoMap.put("modelName", tb.getTableClassName());
				daoMap.put("modelMic", nameStr);	//首字母小写
				// /文件生成的文件路径不存在进行直接生成
				file = new File(this.getOutputDirectoryroot()+File.separator
						+ this.getOutputDirectorydao());
				if (!file.exists())
					file.mkdirs();

				fos = new FileOutputStream(filePath);
				writer = new OutputStreamWriter(fos, Dic.UTF_8);
				template = freeMarkerConfigurer.getConfiguration().getTemplate(Dic.DAO_FLT);
				template.process(daoMap, writer, new DefaultObjectWrapper());
				log.info("-------------dao Gen end-------------");

				log.info("-------------daomapper Gen start-------------");
				filePath = this.getOutputDirectoryroot()+File.separator + this.getOutputDirectorydaoImpl()+File.separator
					+ tb.getTableClassName()+Dic.DAO + Dic.XMLSUF;
				file = new File(filePath);
				if(file.exists()) 
					file.delete();
				Map daoImplMap = new HashMap();
				daoImplMap.put("projectName", this.getProjectName());
				daoImplMap.put("author", this.getAuthor());
				daoImplMap.put("datetime", DateUtility.getFormatDate(DateUtility.getCurrentTime(), DateUtility.DateTimeFormat));
				daoImplMap.put("tableName", tb.getTableName());
				daoImplMap.put("package", outputDirectorydaoImpl.replaceAll("/", "."));
				daoImplMap.put("modelimport", outputDirectorymodel.replaceAll("/", ".")+"."+tb.getTableClassName());
				daoImplMap.put("modelName", tb.getTableClassName());
				daoImplMap.put("modelMic", nameStr);	//首字母小写
				// /文件生成的文件路径不存在进行直接生成
				file = new File(this.getOutputDirectoryroot()+File.separator + this.getOutputDirectorydaoImpl());
				if (!file.exists())
					file.mkdirs();
				
				fos = new FileOutputStream(filePath);
				writer = new OutputStreamWriter(fos, Dic.UTF_8);
				template = freeMarkerConfigurer.getConfiguration().getTemplate(Dic.DAO_IMPL_FLT);
				template.process(daoImplMap, writer, new DefaultObjectWrapper());
				log.info("-------------ServiceImpl Gen end-------------");
				
				
				
				
				
				
				log.info("-------------action Gen start-------------");
				filePath = this.getOutputDirectoryroot()+File.separator
							+ this.getOutputDirectoryaction()+File.separator
							+ tb.getTableClassName()+Dic.ACTION + Dic.JAVASUF;
				file = new File(filePath);
				if(file.exists()) file.delete();
				Map actionMap = new HashMap();
				actionMap.put("projectName", this.getProjectName());
				actionMap.put("author", this.getAuthor());
				actionMap.put("datetime", DateUtility.getFormatDate(DateUtility.getCurrentTime(), DateUtility.DateTimeFormat));
				
				actionMap.put("package", outputDirectoryaction.replaceAll("/", "."));
				actionMap.put("modelimport", outputDirectorymodel.replaceAll("/", ".")+"."+tb.getTableClassName());
				actionMap.put("managerimport", outputDirectoryservice.replaceAll("/", ".")+"."+tb.getTableClassName()+Dic.SERVICE);
				actionMap.put("modelName", tb.getTableClassName());
				actionMap.put("uncapModelName", tb.getUnCaptableClassName());
				actionMap.put("modelMic", nameStr);	//首字母小写
				// /文件生成的文件路径不存在进行直接生成
				file = new File(this.getOutputDirectoryroot()+File.separator+ this.getOutputDirectoryaction());
				if (!file.exists())
					file.mkdirs();

				fos = new FileOutputStream(filePath);
				writer = new OutputStreamWriter(fos, Dic.UTF_8);
				template = freeMarkerConfigurer.getConfiguration().getTemplate(Dic.ACTION_FLT);
				template.process(actionMap, writer, new DefaultObjectWrapper());
				log.info("-------------action Gen end-------------");
				
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}// 加载资源文件
			catch (TemplateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (fos != null)
						fos.close();
					if (writer != null)
						writer.close();
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		}
		
	}
	
	/**
	 * @描述: 执行大小写转换
	 * @作者: WeiYC
	 * @日期:2016-11-30
	 * @修改内容
	 * @参数： @param code
	 * @参数： @return    
	 * @return String   
	 * @throws
	 */
	public static String doChange(String code){
		char[] chars = new char[1];
        chars[0] = code.charAt(0);
        String temp = new String(chars);
        if (chars[0] >= 'A' && chars[0] <= 'Z') {//当为字母时，则转换为小写
            return code.replaceFirst(temp, temp.toLowerCase());
        }else{
        	return "";
        }
	}
	
	public FreeMarkerConfigurer getFreeMarkerConfigurer() {
		return freeMarkerConfigurer;
	}

	public void setFreeMarkerConfigurer(
			FreeMarkerConfigurer freeMarkerConfigurer) {
		this.freeMarkerConfigurer = freeMarkerConfigurer;
	}

	public String getOutputDirectoryroot() {
		return outputDirectoryroot;
	}

	public void setOutputDirectoryroot(String outputDirectoryroot) {
		this.outputDirectoryroot = outputDirectoryroot;
	}

	public String getOutputDirectorymodel() {
		return outputDirectorymodel;
	}

	public void setOutputDirectorymodel(String outputDirectorymodel) {
		this.outputDirectorymodel = outputDirectorymodel;
	}

	public String getOutputDirectoryservice() {
		return outputDirectoryservice;
	}

	public void setOutputDirectoryservice(String outputDirectoryservice) {
		this.outputDirectoryservice = outputDirectoryservice;
	}

	public String getOutputDirectoryserviceImpl() {
		return outputDirectoryserviceImpl;
	}

	public void setOutputDirectoryserviceImpl(String outputDirectoryserviceImpl) {
		this.outputDirectoryserviceImpl = outputDirectoryserviceImpl;
	}

	public String getOutputDirectoryaction() {
		return outputDirectoryaction;
	}

	public void setOutputDirectoryaction(String outputDirectoryaction) {
		this.outputDirectoryaction = outputDirectoryaction;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getProjectName() {
		return projectName;
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public TableUtil getTableUtil() {
		return tableUtil;
	}

	public void setTableUtil(TableUtil tableUtil) {
		this.tableUtil = tableUtil;
	}
	public String getSchema() {
		return schema.trim().equals("no")? "":schema.trim();
	}

	public void setSchema(String schema) {
		this.schema = schema.trim();
	}

	public String getOutputDirectorydao() {
		return outputDirectorydao;
	}

	public void setOutputDirectorydao(String outputDirectorydao) {
		this.outputDirectorydao = outputDirectorydao;
	}

	public String getOutputDirectorydaoImpl() {
		return outputDirectorydaoImpl;
	}

	public void setOutputDirectorydaoImpl(String outputDirectorydaoImpl) {
		this.outputDirectorydaoImpl = outputDirectorydaoImpl;
	}
	
	
}
